<style lang="scss">
.z-directory-select {
  &__con {
    position: relative;
  }
  &__stack {
    padding: 10px;
    border: 1px solid #eee;
    border-radius: 4px;
    &:not(.is-last) {
      display: none;
    }
  }
  .el-tag {
    margin-right: 10px;
    margin-bottom: 10px;
  }
  [disabled] {
    color: #ccc;
  }
}
</style>

<template>
  <div class="z-directory-select">
    <zw-row style="grid-template-columns: 1fr 230px" gutter="10px">
      <z-space vertical>
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item v-for="stack in stacks"
                              :key="stack.id"
                @click.native="setCurIsLast(stack)"
          >
            {{stack.label}}
          </el-breadcrumb-item>
        </el-breadcrumb>
        <div class="z-directory-select__con">
          <div class="z-directory-select__stack"
               :class="{'is-last': checkIsLast(parent) }"
               v-for="parent in stacks" :key="parent.id">
            <template v-if="parent.children">
              <zw-layout style="line-height: 1.5" row>
                <el-checkbox
                    style="margin-right: 6px;"
                    @change="toggleCheckAll(parent.id, parent.children)"
                    v-model="checkedAll[parent.id]"></el-checkbox>
                <div>全选</div>
              </zw-layout>
              <zw-layout row style="align-items: center; line-height: 1.7"
                         v-for="item in parent.children"
                         :disabled="!item.children"
              >
                <el-checkbox
                    style="margin-right: 6px;"
                    @change="onItemChange(item, parent)"
                    :ref="item.id"
                    v-model="checkedMap[item.id]"></el-checkbox>
                <div style="line-height: 1"

                     @click="selectNextLevel(item, parent)">{{item.label}}</div>
              </zw-layout>
            </template>
          </div>
        </div>
      </z-space>
      <div  v-loading="!reload">
<!--        {{checkedMap}}-->

        <div class="z-directory-select__tags"

        >
          <el-tag
              v-if="reload"
              class="z-directory-select__tag"
              closable
              @close="onClickTagClose(tag[1])"
              v-for="tag in sortMap"
              :key="tag[1].id"
              :ref="tag[1].id"
          >{{tag[1].label}}</el-tag>
        </div>

<!--        <div class="z-directory-select__tags"-->

<!--        >-->
<!--          <el-tag-->
<!--              v-if="reload"-->
<!--              class="z-directory-select__tag"-->
<!--              closable-->
<!--              @close="onClickTagClose(tag)"-->
<!--              v-for="tag in curSelectArrData"-->
<!--              :key="tag.id"-->
<!--          >{{tag.label}}</el-tag>-->
<!--        </div>-->
      </div>
    </zw-row>
  </div>
</template>

<script>
let flatten = (children, extractChildren, level, parent) => Array.prototype.concat.apply(
    children.map(x => ({ ...x, level: level || 1, parent: parent || null })),
    children.map(x => flatten(extractChildren(x) || [], extractChildren, (level || 1) + 1, x.id))
);

let extractChildren = x => x.children;

let checker = (arr, target) => target.every(v => arr.includes(v));

export default {
  name: 'ZDirectorySelect',
  props: {
    data: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  mounted() {
    this.stacks = []
    this.pushStack(this.data)
    this.flatArr = flatten(extractChildren(this.data), extractChildren)
  },
  data() {
    return {
      reload: true,
      flatArr: [],
      checkedAll: {},
      checkedMap: {},
      stacks: [],
      sortMap: new Map(),
      curSelectArrData: []
    }
  },
  computed: {
    curSelectArrCom() {
      this.reload;
      return this.curSelectArr();
    }
  },
  watch: {
    checkedAll() {
      this.forceReload()
    }
  },
  methods: {
    setChecked(keys = []) {
      let self = this;
      self.reload = false
      keys.forEach(key => {
        this.checkedMap[key] = true;
        let item = this.flatArr.find(v => v.id === key);
        if (item) {
          // console.log(item)
          self.$nextTick(() => {
            self.detectSortMap(item, true)
          })
        }
      });
      self.$nextTick(
          () => {
            self.checkParentIsCheckedAll(this.data);
            setTimeout(() => {
              self.reload = true
            }, 150)
          }
      )
    },
    getCheckedIDS() {
      return Object.entries(this.checkedMap).filter(([k, v]) => {
        return v
      }).map(([k, v]) => {
        return k
      })
    },
    curSelectArr() {
      let keys = this.getCheckedIDS()
      return this.flatArr.filter(item => {
        return keys.includes(item.id)
      })
    },
    checkIsLast(item) {
      if (this.stacks.length > 0) {
        return this.stacks[this.stacks.length - 1].id === item.id
      }
      return true
    },
    detectSortMap(item, val) {
      if (val) {
        this.sortMap.set(item.id, item)
      } else {
        this.sortMap.delete(item.id)
      }
    },
    onItemChange(item, parent) {
      let val = this.checkedMap[item.id];
      this.checkParentIsCheckedAll(parent);
      this.detectSortMap(item, val)
    },
    checkParentIsCheckedAll(parent) {
      let keys = this.getCheckedIDS()
      // let id = parent.id;
      let ids = parent.children.map(v => v.id)

      let isAllIn = checker(keys, ids);
      // console.log('isAllIn', isAllIn)
      this.checkedAll[parent.id] = isAllIn;
      // this.forceReload()
    },
    pushStack(data) {
      // console.log(data)
      let obj = {
        id: ZY.rid(),
         ...data
      }
      this.stacks.push(obj)
    },
    selectNextLevel(item, parent) {
      // console.log('selectNextLevel', item, parent)
      if (item.children) {
        this.pushStack(item);
        this.checkParentIsCheckedAll(item)
      }
    },
    setCurIsLast(item) {
      // console.log('item', item.id, this.stacks)
      let myIndex = this.stacks.findIndex(level => level.id === item.id);
      if (myIndex > -1) {
        if ( this.stacks.length > 1) {
          this.stacks.splice(myIndex + 1)
        }
      }
    },
    // 全选当前列
    toggleCheckAll(id, children = []) {
      let self = this;
      let curVal = self.checkedAll[id]
      // console.log('sdsdsds', curVal)
      children.forEach(item => {
        self.checkedMap[item.id] = curVal;
        self.detectSortMap(item, curVal)
      })
      // this.forceReload()
    },
    forceReload() {
      // this.curSelectArrData = this.curSelectArr()
    },
    onClickTagClose(tag) {
      let parentId = tag.parent;
      let parent = this.flatArr.find(v => v.id  === parentId);
      if (!parentId) {
        parentId = this.data.id
        parent = this.data
      }
      // this.checkedMap[tag.id] = false

      this.$set(this.checkedMap, tag.id, false)

      console.log('onClickTagClose', tag.id, this.checkedMap, this.$refs[tag.id])
      if (this.$refs[tag.id]) {
        // this.$refs[tag.id][0].value = false
        this.$refs[tag.id][0].$emit('change');
      }

      this.forceReload()
      // this.$refs[tag.id].isChecked = false
    }
  }
}
</script>
